package com.kc.gb.device.plugins.ptl;

import ATOPSTD.AbleAPI;
import ATOPSTD.AbleLightAPI;
import ATOPSTD.TagRcvMsg;
import cn.hutool.core.io.FileUtil;
import com.kc.gb.base.dto.Result;
import com.kc.gb.base.dto.DeviceType;
import com.kc.gb.device.common.enums.PtlDriver;
import com.kc.gb.device.common.interfaces.IHardware;
import com.kc.gb.device.common.properties.DeviceProperties;
import com.kc.gb.device.common.utils.I18NHelper;
import com.kc.gb.device.common.utils.SpringHelper;
import com.kc.gb.device.plugins.ptl.events.support.PtlPublishEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Arrays;

@Slf4j
@Service("PTL")
public class PTLHardware implements IHardware {

    @Resource
    DeviceProperties deviceProperties;

    @Resource
    ThreadPoolTaskScheduler scheduledThreadPoolExecutor;

    private Result INITIALIZE_RESULT = Result.success();

    @Override
    public DeviceType getDeviceType() {
        return DeviceType.PTL;
    }

    @Override
    public boolean isEnabled() {
        return deviceProperties.isDevicePtlEnabled();
    }

    @Override
    public Result<?> isConnected() throws Exception {
        return INITIALIZE_RESULT;
    }

    @Override
    public boolean testConnect(String ip, int port) throws Exception {
        return false;
    }

    @Override
    public Result<?> initialize() throws Exception {
        String driver = deviceProperties.getDevicePtlImpl();
        if(StringUtils.equalsIgnoreCase(PtlDriver.DEFAULT.getImpl(), driver)){
            String message = PtlDriver.DEFAULT.name() + "connected";
            return Result.success(message);
        }
        int deviceId = deviceProperties.getDevicePtlControlID();
        String ip = deviceProperties.getDevicePtlIP();
        int port = deviceProperties.getDevicePtlPort();
        writeIpIndexFile(PTLHardware.class,ip,String.valueOf(port),String.valueOf(deviceId));
        boolean started = AbleLightAPI.start(deviceId);
        log.info("startup start:{}", started);
        if(started){
            startReceiveMessage();
        }
        return Result.success();
    }

    @Override
    public void afterInitialize(Result<?> result) throws Exception {
        this.INITIALIZE_RESULT = result;
    }

    private void startReceiveMessage(){
        Runnable command = new Runnable() {
            @Override
            public void run() {
                try {
                    TagRcvMsg tagRcvMsg = new TagRcvMsg();
                    int num = AbleAPI.AB_Tag_RcvUIDMsg(tagRcvMsg);
                    SpringHelper.getApplicationContext().publishEvent(new PtlPublishEvent(tagRcvMsg));
                } catch (Exception e) {
                    log.error(e.getMessage());
                    throw new RuntimeException(e);
                }
            }
        };
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(command,0l);
    }

    @Override
    public void stopConnect() {

    }

    public static String getRootPath(Class<?> clazz) {
        String path = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
        File root = new File(path);
        String rootPath = root.getParentFile().getPath();
        if (rootPath.endsWith("target")) {
            rootPath = rootPath + File.separator + "classes";
        }
        log.info("light control##rootPath=" + rootPath);
        return rootPath;
    }

    private void writeIpIndexFile(Class<?> clazz,String ip,String port,String deviceId) throws IOException {
        String filePath = getRootPath(clazz);
        log.info("light control##IPINDEX filePath:{}", filePath);
        File file = new File(filePath, "IPINDEX");
        if (!file.exists()) {
            file.createNewFile();
        }
        log.info("light control##IPINDEX file:{}", file.getAbsolutePath());
        String deviceData = deviceId + " " + port + " " + ip;
        FileUtil.writeLines(Arrays.asList(deviceData), file, Charset.defaultCharset());
    }
}
